package com.atguigu.gmall.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import redis.clients.jedis.Jedis;

import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @Author lizhenchao@atguigu.cn
 * @Date 2021/7/31 15:13
 */
public class DimUtil {
    public static JSONObject readDimFromPhoenix(Connection phoenixConn, String tableName, String id) throws SQLException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // 通过jdbc去Phoenix查询数据
        String sql = "select * from " + tableName + " where id = ?";
        
        List<JSONObject> list = JdbcUtil.<JSONObject>queryList(phoenixConn, sql, new Object[]{id}, JSONObject.class);
        
        return list.size() == 0 ? new JSONObject() : list.get(0);
    }
    
    public static JSONObject readDimFromRedis(Jedis client, String tableName, String id) {
        
        String key = getRedisDimKey(tableName, id);
        
        String value = client.get(key);
        if (value != null) {
            // 每个key如果读取到一次之后, 应该把过期重新设置24小时
            client.expire(key, 24 * 6 * 60);
            return JSON.parseObject(value);
        }
        return null;
    }
    
    public static JSONObject readDim(Connection phoenixConn, Jedis client, String tableName, String id) throws InvocationTargetException, SQLException, InstantiationException, IllegalAccessException {
        
        // 1.先从redis读取
        JSONObject obj = readDimFromRedis(client, tableName, id);
        if (obj != null) {
//            System.out.println("走缓存: " + tableName + "  " + id);
            return obj;
        } else {
//            System.out.println("走数据库: " + tableName + "  " + id);
            obj = readDimFromPhoenix(phoenixConn, tableName, id);
//            System.out.println("phoenix: " + obj);
            // 把obj写入到redis
            writeDimToRedis(client, tableName, id, obj);
//            System.out.println("db: " + client.getDB());
            return obj;
            
        }
        
    }
    
    // 向缓存写入维度
    private static void writeDimToRedis(Jedis client, String tableName, String id, JSONObject obj) {
        String key = getRedisDimKey(tableName, id);
        String value = obj.toJSONString();
        client.setex(key, 24 * 60 * 60, value);
        
    }
    
    private static String getRedisDimKey(String tableName, String id) {
        return tableName + ":" + id;
    }
}
/*

redis中存储的维度信息的时候, 使用的数据结构?
    string list set hash zset
    
string:
    key             value
    表名_id         json格式字符串
    
    优点: 读写方便, 可以给每条单独设置过期时间
    缺点: key过多
            解决: 可以使用单独的key
            
list:
    key             value
    表名             {}, {}
    
    读取的效率特别低
    
set:

hash
    key             field           value
    表名              id              {}
    
    设置过期时间:
        不能单独的给每条数据设置过期时间
    
    
 */